﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using workflowMVC.Models;
using DataTool;
using OneGateWF;
using Common;
using DataTables;
using System.Web.Security;


namespace workflowMVC.Controllers
{
    public class ContestController : Controller
    {
        //
        // GET: /Contest/

        public ActionResult Index()
        {
            return View();
        }

        [Authorize(Roles="Admin")]
        public ActionResult Create()
        {
            wfdbEntities db = new wfdbEntities();
            ContestModel c = new ContestModel();
            c.field = new Dictionary<string, bool>();
            foreach (string s1 in Roles.GetUsersInRole("Judge"))
                c.field[s1+" - " + Util.getName(s1)] = false;
            return View(c);
        }

        [HttpPost]
        [Authorize(Roles = "Admin")]
        public ActionResult Create(ContestModel m)
        {
            if (ModelState.IsValid )
            {
                if (!m.field.Select(x => x.Value).Contains(true))
                {
                    ModelState.AddModelError("field", "Phải lựa chọn ban giám khảo");
                    return View(m);
                }
                CONTEST c = new CONTEST();
                c.Title = m.Title;
                c.Description = m.Description;
                c.ExpDate = m.ExpDate;
                List<string> Judges = new List<string>();
                string unToStore = "";

                foreach (KeyValuePair<string, bool> f in m.field)
                {
                    if (f.Value)
                    {
                        string un = f.Key.Split('-').ElementAt(0).TrimEnd();
                        Judges.Add(un);
                        unToStore += un + ";";
                    }
                }
                c.Judges = unToStore.Remove(unToStore.Length - 1);
                ContestHost h = new ContestHost();
                h.InvokeContestWF(c, Judges);
                ViewBag.NotifyResult = "Tạo cuộc thi thành công";
                return View("NotifyResult");
            }
            return View(m);
        }

        [Authorize(Roles = "Student")]
        public ActionResult Post(Guid Id)
        {
            wfdbEntities db = new wfdbEntities();
            if(db.CONTESTs.Where(x => x.Id == Id && x.Status == 1).FirstOrDefault() == null)
                return View("Error");
            return View();
        }

        [ValidateInput(false)] 
        [HttpPost]
        [Authorize(Roles = "Student")]
        public ActionResult Post(CreatePostModel p,Guid Id)
        {
            if (ModelState.IsValid)
            {
                ContestHost h = new ContestHost();
                SUBMISSION sub = new SUBMISSION();
                sub.Username = User.Identity.Name;
                sub.Date = DateTime.Now;
                sub.TestContent = p.TestContent;
                sub.Id = Guid.NewGuid();
                sub.ContestId = Id;
                sub.Tittle = p.Tittle;
                h.SendSubmission(Id, new SendSubmissionSession() { sub = sub });
                ViewBag.NotifyResult = "Bạn đã gửi bài thành công";
                return View("NotifyResult");
            }
            return View();
        }



        [Authorize(Roles = "Student")]
        public ActionResult OpeningList()
        {
            ViewBag.datasource = "OpeningListData";
            return View("List");
        }

        [Authorize(Roles = "Student")]
        public JsonResult OpeningListData()
        {
            wfdbEntities db = new wfdbEntities();
            var data = db.CONTESTs.Include("CONTESTSTATU").Where(x=> x.Status == 1).AsEnumerable().Select(x => new ListContestModel
            {
                Title = x.Title,
                Status = x.CONTESTSTATU.Description,
                CreateDate = x.CreateDate.Value,
                Id = x.Id
            }
                );
            var cs = new DataTableParser<ListContestModel>(Request, data.AsQueryable()).Parse();
            cs.aaData.ForEach(x =>
            {
                string idz = x[3];
                x[3] = Util.getsTableLink(new { @class = Util.detail }, new { title = "Xem", href = Url.Action("Detail", new { id = x[3] }) });
            });
            return Json(cs);
        }

        [Authorize(Roles = "Judge")]
        public ActionResult GradingList()
        {
            ViewBag.datasource = "GradingListData";
            return View("List");
        }

        [Authorize(Roles = "Judge")]
        public JsonResult GradingListData()
        {
            wfdbEntities db = new wfdbEntities();
            var data = db.CONTESTs.Include("CONTESTSTATU").Where(x => x.Status == 2)
                .AsEnumerable().DefaultIfEmpty().Where(x => { 
                    if(x == null || String.IsNullOrEmpty(x.Judges))
                        return false;
                    else return
                x.Judges.Split(';').Contains(User.Identity.Name);} ).Select(x => new ListContestModel
            {
                Title = x.Title,
                Status = x.CONTESTSTATU.Description,
                CreateDate = x.CreateDate.Value,
                Id = x.Id
            }
                );
            var cs = new DataTableParser<ListContestModel>(Request, data.AsQueryable()).Parse();
            cs.aaData.ForEach(x =>
            {
                string idz = x[3];
                x[3] = Util.getsTableLink(new { @class = Util.detail }, new { title = "Xem", href = Url.Action("Detail", new { id = x[3] }) });
                x[3] += Util.getsTableLink(new { @class = Util.calculator }, new { title = "Xem Bài thi", href = Url.Action("PostListFromContest", new { id = idz }) });
            });
            return Json(cs);
        }

        [Authorize(Roles="Admin")]
        public ActionResult List()
        {
            ViewBag.datasource = "ListData";
            return View();
        }
        [Authorize(Roles = "Admin")]
        public JsonResult ListData()
        {
            wfdbEntities db = new wfdbEntities();
            var data = db.CONTESTs.Include("CONTESTSTATU").AsEnumerable().Select(x => new ListContestModel
                {
                    Title = x.Title,
                    Status = x.CONTESTSTATU.Description,
                    CreateDate = x.CreateDate.Value,
                    Id = x.Id
                }
                );
            var cs = new DataTableParser<ListContestModel>(Request, data.AsQueryable()).Parse();
            cs.aaData.ForEach(x =>
                {
                    string idz = x[3];
                    x[3] = Util.getsTableLink(new { @class = Util.detail }, new { title = "Xem", href = Url.Action("Detail", new { id = x[3] }) });
                    if (User.IsInRole("Judge") && x[2] == "chờ chấm điểm")
                        x[3] += Util.getsTableLink(new { @class = Util.calculator }, new { title = "Xem Bài thi", href = Url.Action("PostListFromContest", new { id = idz }) });
                }
                );
            return Json(cs);
        }

        public ActionResult Detail(Guid id)
        {
            wfdbEntities db = new wfdbEntities();
            var c = db.CONTESTs.Include("CONTESTSTATU").SingleOrDefault(x => x.Id == id);
            if (c == null)
                return View("Error");
            DetailContentModel m = new DetailContentModel();
            m.CreateDate = c.CreateDate.Value;
            m.Id = id;
            m.Status = c.CONTESTSTATU.Description;
            m.StatusValue = c.Status.Value;
            m.ExpDate = c.ExpDate.Value;
            m.Title = c.Title;
            m.Description = c.Description;
            m.Judges = c.Judges.Split(';').ToList();
            ViewBag.datasource = Url.Action("ResultList", new { id = id });
            return View(m);
        }

        public ActionResult ResultList(Guid id)
        {
            wfdbEntities db = new wfdbEntities();
            var c = db.CONTESTs.Where(x => x.Id == id).FirstOrDefault();
            var data = c.SUBMISSIONs.AsEnumerable().Select(x => new PostLink
                {
                    Grade = x.FinalGrade.Value.ToString(),
                    Name = db.STUDENTs
                        .Where(z => z.NumCode == x.Username).FirstOrDefault().Name,
                    PostName = x.Tittle,
                    PostId = x.Id
                });
            var cs = new DataTableParser<PostLink>(Request, data.AsQueryable()).Parse();
            cs.aaData.ForEach(x =>
            {
                x[3] = Util.getsTableLink(new { @class = Util.detail }, new { title = "Xem", href = Url.Action("GradePost", new { id = x[3] }) });
            });
            return Json(cs);
        }

        [HttpPost]
        [Authorize(Roles="Admin")]
        public ActionResult StopAcceptPost(Guid Id)
        {
            ContestHost h = new ContestHost();
            h.StopAcceptPost(Id);
            ViewBag.NotifyResult = "Dừng nhận bài thi thành công";
            return View("NotifyResult");
        }


        public ActionResult GradePost(Guid Id)
        {
            wfdbEntities db = new wfdbEntities();
            var post = db.SUBMISSIONs.SingleOrDefault(x => x.Id == Id);
            if(post == null)
                return View("Error");
            GradePostModel m = new GradePostModel();
            m.ContestTitle = post.CONTEST.Title;
            m.CreateDate = post.Date.Value;
            m.Name = db.STUDENTs.SingleOrDefault(x => x.NumCode == post.Username).Name;
            m.NumCode = post.Username;
            m.PostTittle = post.Tittle;
            m.TestContent = post.TestContent;
            m.ContestId = post.ContestId.Value;
            m.ContestStatusValue = post.CONTEST.Status.Value;
            try
            {
                m.Judges = post.CONTEST.Judges.Split(';').ToList();
            }
            catch
            {
                m.Judges = new List<string>();
            }
            if(post.CONTEST.Status == 3)
            {
                m.jG = new List<JudgeGrade>();
                foreach (var i in post.SUBMISSIONGRADEs)
                {
                    m.jG.Add(new JudgeGrade
                    {
                        Grade = i.Grade.Value,
                        Judge = i.Username
                    });
                }
                m.TotalGrade = post.FinalGrade.Value.ToString() ;
            }
            m.IsGraded = post.SUBMISSIONGRADEs
                .Where(z => z.Username == User.Identity.Name).Count() == 0 ? false : true;
            if(m.IsGraded)
                m.grade = post.SUBMISSIONGRADEs.SingleOrDefault(x => x.Username == User.Identity.Name).Grade.Value;
            
            List<SelectListItem> gradez = new List<SelectListItem>();
            var grades = Enumerable.Range(1, 5);

            foreach (var r in grades)
            {
                gradez.Add(new SelectListItem
                {
                    Value = r.ToString(),
                    Text = r.ToString(),
                });
            }
            ViewBag.gradez = new SelectList(gradez, "Value", "Text");

            return View(m);
        }

        [HttpPost]
        [Authorize(Roles="Judge")]
        public ActionResult GradePost(GradePostModel m,Guid Id)
        {
            if (ModelState.IsValid)
            {
                wfdbEntities db = new wfdbEntities();
                
                ContestHost h = new ContestHost();
                h.GradePost(new SubmissionGradeSession
                    {
                        Grade = m.grade,
                        SubId = Id,
                        Username = User.Identity.Name,
                    }, m.ContestId
                    );
                ViewBag.NotifyResult = "Bạn đã chấm điểm thành công";
                return View("NotifyResult");
            }
            List<SelectListItem> gradez = new List<SelectListItem>();
            var grades = Enumerable.Range(1, 5);

            foreach (var r in grades)
            {
                gradez.Add(new SelectListItem
                {
                    Value = r.ToString(),
                    Text = r.ToString(),
                });
            }
            ViewBag.gradez = new SelectList(gradez, "Value", "Text");
            return View(m);
        }

        public ActionResult PostListFromContest(Guid Id)
        {
            GradePostTableModel m = new GradePostTableModel();
            wfdbEntities db = new wfdbEntities();
            var p = db.CONTESTs.SingleOrDefault(x => x.Id == Id);
            if (p == null)
                return View("Error");
            m.ContestTitle = p.Title;
            m.Id = p.Id;
            m.DataLink = Url.Action("PostListFormContestData", new { id = Id });
            return View(m);
        }

        [Authorize(Roles="Judge")]
        public ActionResult PostListFormContestData(Guid id)
        {
            wfdbEntities db = new wfdbEntities();
            var data = db.SUBMISSIONs.Where(x => x.ContestId == id).AsEnumerable().Select(
                x => new GradePostListModel()
                {
                    PostId = x.Id,
                    CreateDate = x.Date.Value,
                    Name = db.STUDENTs.SingleOrDefault(z => z.NumCode == x.Username).Name,
                    NumCode = x.Username,
                    PostTittle = x.Tittle,
                    IsGraded = x.SUBMISSIONGRADEs.Where(z => z.Username == User.Identity.Name).Count() == 0 ? true : false
                });
            var cs = new DataTableParser<GradePostListModel>(Request, data.AsQueryable()).Parse();
            cs.aaData.ForEach(x =>
            {
                x[5] = Util.getsTableLink(new { @class = Util.detail }, new { title = "Xem", href = Url.Action("GradePost", new { id = x[5] }) });
                x[4] = x[4] == "True" ? "Chưa chấm" : "Đã chấm";
            });
            return Json(cs);
        }

        public ActionResult MySubmissionList()
        {
            ViewBag.datasource = Url.Action("MySubmissionData");
            return View();
        }

        public ActionResult MySubmissionData()
        {
            wfdbEntities db = new wfdbEntities();
            var data = db.SUBMISSIONs.Where(x => x.Username == User.Identity.Name).AsEnumerable().Select(
                x => new MySubmListModel()
                {
                    PostId = x.Id,
                    CreateDate = x.Date.Value,
                    ContestName = x.ContestId.Value.ToString(),
                    PostTittle = x.Tittle,
                    IsGraded = x.CONTEST.Status == 3
                });
            var cs = new DataTableParser<MySubmListModel>(Request, data.AsQueryable()).Parse();
            cs.aaData.ForEach(x =>
            {
                x[1] = Util.getLinkForContest(x[1],Url);
                x[4] = Util.getsTableLink(new { @class = Util.detail }, new { title = "Xem", href = Url.Action("GradePost", new { id = x[4] }) });
                x[3] = x[3] == "True" ? "Đã chấm" : "Chưa chấm";
            });
            return Json(cs);
        }
    }
}
